class Nav2D {
  constructor(canvasId, socket) {
      this.canvas = document.getElementById(canvasId);
      this.ctx = this.canvas.getContext('2d');
      this.socket = socket;
      this.transform = {
          scale: 20,
          offsetX: this.canvas.width / 2,
          offsetY: this.canvas.height / 2,
          minScale: 5,
          maxScale: 100
      };
      
      // 状态数据
      this.mapImage = null;
      this.mapInfo = null;
      this.robotPose = null;
      this.laserData = null;
      this.currentPath = [];
      this.waypoints = [];
      this.isDragging = false;
      this.dragStart = { x: 0, y: 0 };
      
      // 初始化事件监听
      this.initEventListeners();
      this.initSocketHandlers();
      
      // 初始渲染
      this.render();
  }
  
  initEventListeners() {
      // 地图平移
      this.canvas.addEventListener('mousedown', (e) => {
          if (e.button === 0) { // 左键
              this.isDragging = true;
              this.dragStart = {
                  x: e.clientX - this.transform.offsetX,
                  y: e.clientY - this.transform.offsetY
              };
              this.canvas.style.cursor = 'grabbing';
          }
      });
      
      document.addEventListener('mousemove', (e) => {
          if (this.isDragging) {
              this.transform.offsetX = e.clientX - this.dragStart.x;
              this.transform.offsetY = e.clientY - this.dragStart.y;
              this.render();
          }
      });
      
      document.addEventListener('mouseup', () => {
          this.isDragging = false;
          this.canvas.style.cursor = 'crosshair';
      });
      
      // 地图缩放
      this.canvas.addEventListener('wheel', (e) => {
          e.preventDefault();
          const zoomFactor = e.deltaY > 0 ? 0.9 : 1.1;
          const newScale = this.transform.scale * zoomFactor;
          
          if (newScale > this.transform.minScale && 
              newScale < this.transform.maxScale) {
              const mouseX = e.clientX - this.canvas.getBoundingClientRect().left;
              const mouseY = e.clientY - this.canvas.getBoundingClientRect().top;
              
              // 计算相对于画布的坐标
              const worldX = (mouseX - this.transform.offsetX) / this.transform.scale;
              const worldY = (mouseY - this.transform.offsetY) / this.transform.scale;
              
              // 应用缩放
              this.transform.scale = newScale;
              
              // 调整偏移使缩放中心保持鼠标位置
              this.transform.offsetX = mouseX - worldX * this.transform.scale;
              this.transform.offsetY = mouseY - worldY * this.transform.scale;
              
              this.render();
          }
      });
      
      // 右键设置目标点
      this.canvas.addEventListener('contextmenu', (e) => {
          e.preventDefault();
          const rect = this.canvas.getBoundingClientRect();
          const worldPos = this.screenToWorld(
              e.clientX - rect.left,
              e.clientY - rect.top
          );
          
          this.socket.emit('set_navigation_goal', {
              x: worldPos.x,
              y: worldPos.y,
              theta: 0
          });
      });
      
      // 双击设置初始位置
      this.canvas.addEventListener('dblclick', (e) => {
          const rect = this.canvas.getBoundingClientRect();
          const worldPos = this.screenToWorld(
              e.clientX - rect.left,
              e.clientY - rect.top
          );
          
          this.showInitialPoseDialog(worldPos.x, worldPos.y);
      });
  }
  
  initSocketHandlers() {
      // 地图数据
      this.socket.on('map_update', (data) => {
          this.mapInfo = data.info;
          this.loadMapImage();
      });
      
      // 机器人位姿
      this.socket.on('robot_pose', (pose) => {
          this.robotPose = pose;
          this.render();
      });
      
      // 路径更新
      this.socket.on('path_update', (data) => {
          this.currentPath = data.path;
          this.render();
      });
      
      // 激光雷达数据
      this.socket.on('laser_scan', (data) => {
          this.laserData = data;
          this.renderLaserScan();
      });
  }
  
  loadMapImage() {
      fetch('/api/map')
          .then(response => response.blob())
          .then(blob => {
              const url = URL.createObjectURL(blob);
              const img = new Image();
              img.onload = () => {
                  this.mapImage = img;
                  this.autoFitMap();
                  this.render();
              };
              img.src = url;
          });
  }
  
  autoFitMap() {
      if (!this.mapImage || !this.mapInfo) return;
      
      // 计算适合的缩放比例
      const scaleX = this.canvas.width / (this.mapInfo.width * this.mapInfo.resolution);
      const scaleY = this.canvas.height / (this.mapInfo.height * this.mapInfo.resolution);
      this.transform.scale = Math.min(scaleX, scaleY) * 0.9;
      
      // 居中显示
      this.transform.offsetX = (this.canvas.width - this.mapInfo.width * this.mapInfo.resolution * this.transform.scale) / 2;
      this.transform.offsetY = (this.canvas.height - this.mapInfo.height * this.mapInfo.resolution * this.transform.scale) / 2;
  }
  
  screenToWorld(screenX, screenY) {
      return {
          x: (screenX - this.transform.offsetX) / this.transform.scale,
          y: (screenY - this.transform.offsetY) / this.transform.scale
      };
  }
  
  worldToScreen(worldX, worldY) {
      return {
          x: worldX * this.transform.scale + this.transform.offsetX,
          y: worldY * this.transform.scale + this.transform.offsetY
      };
  }
  
  render() {
      this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
      
      // 绘制地图
      if (this.mapImage && this.mapInfo) {
          this.ctx.drawImage(
              this.mapImage,
              0, 0, this.mapImage.width, this.mapImage.height,
              this.transform.offsetX,
              this.transform.offsetY,
              this.mapInfo.width * this.mapInfo.resolution * this.transform.scale,
              this.mapInfo.height * this.mapInfo.resolution * this.transform.scale
          );
      }
      
      // 绘制路径
      this.renderPath();
      
      // 绘制激光雷达数据
      if (this.laserData) {
          this.renderLaserScan();
      }
      
      // 绘制机器人
      if (this.robotPose) {
          this.renderRobot();
      }
      
      // 绘制航点
      this.renderWaypoints();
  }
  
  renderPath() {
      if (this.currentPath.length < 2) return;
      
      this.ctx.beginPath();
      this.ctx.strokeStyle = 'rgba(255, 0, 0, 0.7)';
      this.ctx.lineWidth = 3;
      this.ctx.lineJoin = 'round';
      
      const start = this.worldToScreen(
          this.currentPath[0].x,
          this.currentPath[0].y
      );
      this.ctx.moveTo(start.x, start.y);
      
      for (let i = 1; i < this.currentPath.length; i++) {
          const point = this.worldToScreen(
              this.currentPath[i].x,
              this.currentPath[i].y
          );
          this.ctx.lineTo(point.x, point.y);
      }
      
      this.ctx.stroke();
  }
  
  renderRobot() {
      const screenPos = this.worldToScreen(
          this.robotPose.x,
          this.robotPose.y
      );
      
      this.ctx.save();
      this.ctx.translate(screenPos.x, screenPos.y);
      this.ctx.rotate(this.robotPose.theta);
      
      // 绘制机器人主体
      this.ctx.beginPath();
      this.ctx.arc(0, 0, 10, 0, Math.PI * 2);
      this.ctx.fillStyle = 'rgba(0, 200, 0, 0.8)';
      this.ctx.fill();
      this.ctx.strokeStyle = 'white';
      this.ctx.stroke();
      
      // 绘制方向指示器
      this.ctx.beginPath();
      this.ctx.moveTo(0, 0);
      this.ctx.lineTo(20, 0);
      this.ctx.strokeStyle = 'white';
      this.ctx.lineWidth = 2;
      this.ctx.stroke();
      
      this.ctx.restore();
  }
  
  renderLaserScan() {
      if (!this.laserData || !this.robotPose) return;
      
      this.ctx.save();
      const robotScreenPos = this.worldToScreen(
          this.robotPose.x,
          this.robotPose.y
      );
      this.ctx.translate(robotScreenPos.x, robotScreenPos.y);
      this.ctx.rotate(this.robotPose.theta);
      
      this.ctx.beginPath();
      this.ctx.strokeStyle = 'rgba(0, 255, 255, 0.3)';
      this.ctx.lineWidth = 1;
      
      for (let i = 0; i < this.laserData.ranges.length; i++) {
          const angle = this.laserData.angle_min + i * this.laserData.angle_increment;
          const range = this.laserData.ranges[i];
          
          if (range > this.laserData.range_min && range < this.laserData.range_max) {
              const x = range * Math.cos(angle);
              const y = range * Math.sin(angle);
              
              const point = this.worldToScreen(x, y);
              this.ctx.moveTo(0, 0);
              this.ctx.lineTo(
                  x * this.transform.scale,
                  y * this.transform.scale
              );
          }
      }
      
      this.ctx.stroke();
      this.ctx.restore();
  }
  
  renderWaypoints() {
      this.waypoints.forEach(waypoint => {
          const screenPos = this.worldToScreen(waypoint.x, waypoint.y);
          
          this.ctx.beginPath();
          this.ctx.arc(screenPos.x, screenPos.y, 8, 0, Math.PI * 2);
          this.ctx.fillStyle = 'rgba(0, 0, 255, 0.7)';
          this.ctx.fill();
          this.ctx.strokeStyle = 'white';
          this.ctx.stroke();
          
          // 显示航点序号
          this.ctx.fillStyle = 'white';
          this.ctx.font = 'bold 12px Arial';
          this.ctx.textAlign = 'center';
          this.ctx.textBaseline = 'middle';
          this.ctx.fillText(
              waypoint.id.toString(),
              screenPos.x,
              screenPos.y
          );
      });
  }
  
  showInitialPoseDialog(x, y) {
      const modal = new bootstrap.Modal(document.getElementById('initialPoseModal'));
      document.getElementById('initial-pose-x').value = x.toFixed(2);
      document.getElementById('initial-pose-y').value = y.toFixed(2);
      document.getElementById('initial-pose-theta').value = '0.00';
      
      document.getElementById('confirm-initial-pose').onclick = () => {
          const theta = parseFloat(document.getElementById('initial-pose-theta').value);
          this.socket.emit('set_initial_pose', { x, y, theta });
          modal.hide();
      };
      
      modal.show();
  }
  
  addWaypoint(x, y) {
      const newId = this.waypoints.length > 0 ? 
          Math.max(...this.waypoints.map(w => w.id)) + 1 : 1;
      
      this.waypoints.push({
          id: newId,
          x: x,
          y: y
      });
      
      this.render();
      this.updateWaypointsList();
  }
  
  updateWaypointsList() {
      const listElement = document.getElementById('waypoints-list');
      listElement.innerHTML = this.waypoints.map(waypoint => `
          <div class="waypoint-item">
              <span>#${waypoint.id}: (${waypoint.x.toFixed(2)}, ${waypoint.y.toFixed(2)})</span>
              <button class="btn btn-sm btn-outline-danger remove-waypoint" 
                      data-id="${waypoint.id}">
                  <i class="bi bi-trash"></i>
              </button>
          </div>
      `).join('');
      
      // 添加删除事件
      document.querySelectorAll('.remove-waypoint').forEach(button => {
          button.addEventListener('click', (e) => {
              const id = parseInt(e.target.closest('button').dataset.id);
              this.waypoints = this.waypoints.filter(w => w.id !== id);
              this.updateWaypointsList();
              this.render();
          });
      });
  }
  
  clearWaypoints() {
      this.waypoints = [];
      this.updateWaypointsList();
      this.render();
  }
  
  executeWaypoints() {
      if (this.waypoints.length > 0) {
          this.socket.emit('follow_waypoints', {
              waypoints: this.waypoints.map(w => ({ x: w.x, y: w.y }))
          });
      }
  }
}